//
//  SlideAnimationController.m
//  CustomTabBarTransition
//
//  Created by 朱志佳 on 2019/4/4.
//  Copyright © 2019 朱志佳. All rights reserved.
//

#import "SlideAnimationController.h"

@implementation SlideAnimationController



/*
 在 UITabBarController 的转场里，如果你在动画控制器里实现了 animationEnded: 方法，这个方法会被调用2次。
 而在 NavigationController 和 Modal 转场里没有这种问题，观察函数帧栈也发现比前两种转场多了一次私有函数调用：
 [UITabBarController transitionFromViewController:toViewController:transition:shouldSetSelected:]
 该方法和 UIViewController 的 transitionFromViewController:toViewController:duration:options:animations:completion:
 方法应该是一脉相承的，用于控制器的转换，我在文章里实现自定义容器控制器转场时也用过这个方法来实现自定义转场，不过由于测试不完整我在文章里将这块删掉了。
 
 */

// This is used for percent driven interactive transitions, as well as for
// container controllers that have companion animations that might need to
// synchronize with the main animation.
- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext {
    NSLog(@"%@##%@",NSStringFromClass([self class]),NSStringFromSelector(_cmd));
    return 0.3;
}
// This method can only  be a nop if the transition is interactive and not a percentDriven interactive transition.
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
    NSLog(@"%@##%@",NSStringFromClass([self class]),NSStringFromSelector(_cmd));
    UIView *containerView = transitionContext.containerView;
    
    UIViewController *fromVC = [transitionContext viewControllerForKey:(UITransitionContextFromViewControllerKey)];
    UIViewController *toVC = [transitionContext viewControllerForKey:(UITransitionContextToViewControllerKey)];
    
    UIView *fromView = [transitionContext viewForKey:(UITransitionContextFromViewKey)];
    UIView *toView = [transitionContext viewForKey:(UITransitionContextToViewKey)];
    
    CGFloat translation = containerView.frame.size.width;
    CGAffineTransform toViewTransform = CGAffineTransformIdentity;
    CGAffineTransform fromViewTransform = CGAffineTransformIdentity;
    
    switch (_transitionType) {
        case TransitionTypePush:
        case TransitionTypeRight:
            toViewTransform = CGAffineTransformMakeTranslation(translation, 0);
            fromViewTransform = CGAffineTransformMakeTranslation(-translation, 0);
            break;
        case TransitionTypePop:
        case TransitionTypeLeft:
            toViewTransform = CGAffineTransformMakeTranslation(-translation, 0);
            fromViewTransform = CGAffineTransformMakeTranslation(translation, 0);
            break;
        case TransitionTypePresentation:
            translation = containerView.frame.size.height;
            toViewTransform = CGAffineTransformMakeTranslation(0, translation);
            fromViewTransform = CGAffineTransformMakeTranslation(0, 0);
            break;
        case TransitionTypeDismisssal:
            translation = containerView.frame.size.height;
            toViewTransform = CGAffineTransformMakeTranslation(0, -translation);
            fromViewTransform = CGAffineTransformMakeTranslation(0, translation);
        default:
            break;
    }
    
    switch (_transitionType) {
        case TransitionTypePresentation:
            [containerView addSubview:toView];
            break;
        case TransitionTypeDismisssal:
            [containerView addSubview:toView];
            break;
        default:
            [containerView addSubview:toView];
            break;
    }
    
    toView.transform = toViewTransform;
    
    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        fromView.transform = fromViewTransform;
        toView.transform = CGAffineTransformIdentity;
    } completion:^(BOOL finished) {
        fromView.transform = CGAffineTransformIdentity;
        toView.transform = CGAffineTransformIdentity;
        BOOL isCancelled = [transitionContext transitionWasCancelled];
        [transitionContext completeTransition:!isCancelled];
    }];
}

/// A conforming object implements this method if the transition it creates can
/// be interrupted. For example, it could return an instance of a
/// UIViewPropertyAnimator. It is expected that this method will return the same
/// instance for the life of a transition.
//- (id <UIViewImplicitlyAnimating>) interruptibleAnimatorForTransition:(id <UIViewControllerContextTransitioning>)transitionContext NS_AVAILABLE_IOS(10_0);

// This is a convenience and if implemented will be invoked by the system when the transition context's completeTransition: method is invoked.
- (void)animationEnded:(BOOL) transitionCompleted{
    NSLog(@"%@##%@",NSStringFromClass([self class]),NSStringFromSelector(_cmd));
}

@end
